<?php
/**
 * @copyright 2025 银杏ERP
 * @author 银杏ERP
 * @version 1.0
 * @license http://www.hhyx.xyz
 * @developer Lhf
 */

namespace app\admin\controller\yxerp;

use app\common\controller\Backend;
use app\admin\model\yxerp\Purchase as PurchaseModel;
use app\admin\model\yxerp\PurchaseDetail;
use app\admin\model\yxerp\Supplier;
use app\admin\model\yxerp\Product;
use app\admin\model\yxerp\Warehouse;
use think\db\exception\PDOException;
use think\Exception;
use think\facade\Db;

/**
 * 采购管理控制器
 */
class Purchase extends Backend
{
    /**
     * Purchase模型对象
     * @var object
     */
    protected $model = null;
    
    /**
     * 开启数据限制
     * 表示当前控制器及关联模型的增删改查需要判断当前管理员的数据权限
     * @var bool
     */
    protected $dataLimit = true;
    
    /**
     * 初始化
     */
    public function initialize()
    {
        parent::initialize();
        $this->model = new PurchaseModel();
    }
    
    /**
     * 查看
     */
    public function index()
    {
        $this->request->filter(['strip_tags', 'trim']);
        
        if ($this->request->param('select')) {
            $this->select();
        }
        
        list($where, $sort, $order, $offset, $limit) = $this->buildparams();
        
        $list = $this->model
            ->with(['supplier', 'warehouse', 'creator'])
            ->where($where)
            ->order($sort, $order)
            ->paginate($limit);
            
        $result = ['total' => $list->total(), 'rows' => $list->items()];
        
        return json($result);
    }
    
    /**
     * 添加
     */
    public function add()
    {
        if ($this->request->isPost()) {
            $params = $this->request->post();
            
            if (empty($params['details']) || !is_array($params['details'])) {
                $this->error(__('采购明细不能为空'));
            }
            
            Db::startTrans();
            try {
                // 生成订单编号
                $params['order_no'] = $this->generateOrderNo();
                $params['creator_id'] = $this->auth->id;
                $params['status'] = 'draft'; // 草稿状态
                
                // 计算总金额
                $totalAmount = 0;
                foreach ($params['details'] as $detail) {
                    $totalAmount += $detail['price'] * $detail['quantity'];
                }
                $params['total_amount'] = $totalAmount;
                
                // 保存主单
                $result = $this->model->save($params);
                if ($result === false) {
                    throw new Exception('保存采购单失败');
                }
                
                // 保存明细
                $detailData = [];
                foreach ($params['details'] as $detail) {
                    $detail['purchase_id'] = $this->model->id;
                    $detail['subtotal'] = $detail['price'] * $detail['quantity'];
                    $detailData[] = $detail;
                }
                
                $detailModel = new PurchaseDetail();
                $detailResult = $detailModel->saveAll($detailData);
                if ($detailResult === false) {
                    throw new Exception('保存采购明细失败');
                }
                
                Db::commit();
                $this->success('添加成功');
            } catch (Exception | PDOException $e) {
                Db::rollback();
                $this->error($e->getMessage());
            }
        }
        
        return $this->view->fetch();
    }
    
    /**
     * 编辑
     */
    public function edit($ids = null)
    {
        $row = $this->model->find($ids);
        if (!$row) {
            $this->error(__('数据不存在'));
        }
        
        // 只有草稿状态的订单可以编辑
        if ($row['status'] !== 'draft') {
            $this->error(__('只有草稿状态的采购单可以编辑'));
        }
        
        if ($this->request->isPost()) {
            $params = $this->request->post();
            
            if (empty($params['details']) || !is_array($params['details'])) {
                $this->error(__('采购明细不能为空'));
            }
            
            Db::startTrans();
            try {
                // 更新主单
                $totalAmount = 0;
                foreach ($params['details'] as $detail) {
                    $totalAmount += $detail['price'] * $detail['quantity'];
                }
                $params['total_amount'] = $totalAmount;
                
                // 保存主单
                $result = $row->save($params);
                if ($result === false) {
                    throw new Exception('保存采购单失败');
                }
                
                // 先删除旧的明细
                PurchaseDetail::where('purchase_id', $ids)->delete();
                
                // 保存新的明细
                $detailData = [];
                foreach ($params['details'] as $detail) {
                    $detail['purchase_id'] = $ids;
                    $detail['subtotal'] = $detail['price'] * $detail['quantity'];
                    $detailData[] = $detail;
                }
                
                $detailModel = new PurchaseDetail();
                $detailResult = $detailModel->saveAll($detailData);
                if ($detailResult === false) {
                    throw new Exception('保存采购明细失败');
                }
                
                Db::commit();
                $this->success('编辑成功');
            } catch (Exception | PDOException $e) {
                Db::rollback();
                $this->error($e->getMessage());
            }
        }
        
        // 加载明细
        $row['details'] = PurchaseDetail::where('purchase_id', $ids)
            ->with(['product'])
            ->select();
            
        $this->assign('row', $row);
        return $this->view->fetch();
    }
    
    /**
     * 删除
     */
    public function del($ids = null)
    {
        if ($ids) {
            $pk = $this->model->getPk();
            $list = $this->model->where($pk, 'in', $ids)->select();
            
            $count = 0;
            Db::startTrans();
            try {
                foreach ($list as $item) {
                    // 只能删除草稿状态的订单
                    if ($item->status !== 'draft') {
                        throw new Exception('只有草稿状态的采购单可以删除');
                    }
                    
                    // 删除明细
                    PurchaseDetail::where('purchase_id', $item->id)->delete();
                    
                    // 删除主单
                    $result = $item->delete();
                    if ($result) {
                        $count += 1;
                    }
                }
                
                Db::commit();
                $this->success('成功删除' . $count . '条记录');
            } catch (Exception | PDOException $e) {
                Db::rollback();
                $this->error($e->getMessage());
            }
        }
        
        $this->error(__('参数不正确'));
    }
    
    /**
     * 批量更新
     */
    public function multi($ids = null)
    {
        if ($ids) {
            $pk = $this->model->getPk();
            $admin = $this->auth->id;
            
            $params = $this->request->post();
            $params = array_filter(params_filter($params));
            
            if (empty($params)) {
                $this->error(__('没有需要更新的参数'));
            }
            
            // 不允许通过此方法修改状态
            if (isset($params['status'])) {
                $this->error(__('不允许通过此方法修改状态'));
            }
            
            try {
                $count = 0;
                $list = $this->model->where($pk, 'in', $ids)->select();
                
                foreach ($list as $item) {
                    // 只能修改草稿状态的订单
                    if ($item->status !== 'draft') {
                        continue;
                    }
                    
                    $result = $item->save($params);
                    if ($result !== false) {
                        $count += 1;
                    }
                }
                
                if ($count) {
                    $this->success('成功更新' . $count . '条记录');
                } else {
                    $this->error(__('没有数据被更新'));
                }
            } catch (Exception | PDOException $e) {
                $this->error($e->getMessage());
            }
        }
        
        $this->error(__('参数不正确'));
    }
    
    /**
     * 查看详情
     */
    public function detail($ids = null)
    {
        $row = $this->model->find($ids);
        if (!$row) {
            $this->error(__('数据不存在'));
        }
        
        // 加载明细和关联数据
        $row = $row->with([
            'supplier', 
            'warehouse', 
            'creator',
            'approver',
            'details.product'
        ])->find($ids);
            
        $this->success('获取成功', null, $row);
    }
    
    /**
     * 提交审批
     */
    public function submit($ids = null)
    {
        $row = $this->model->find($ids);
        if (!$row) {
            $this->error(__('数据不存在'));
        }
        
        // 只有草稿状态的订单可以提交审批
        if ($row['status'] !== 'draft') {
            $this->error(__('只有草稿状态的采购单可以提交审批'));
        }
        
        try {
            $result = $row->save([
                'status' => 'pending',
                'submit_time' => date('Y-m-d H:i:s')
            ]);
            
            if ($result !== false) {
                $this->success('提交审批成功');
            } else {
                $this->error(__('提交审批失败'));
            }
        } catch (Exception | PDOException $e) {
            $this->error($e->getMessage());
        }
    }
    
    /**
     * 审批
     */
    public function approval($ids = null)
    {
        $row = $this->model->find($ids);
        if (!$row) {
            $this->error(__('数据不存在'));
        }
        
        // 只有待审批状态的订单可以审批
        if ($row['status'] !== 'pending') {
            $this->error(__('只有待审批状态的采购单可以审批'));
        }
        
        if ($this->request->isPost()) {
            $params = $this->request->post();
            
            if (!isset($params['status']) || !in_array($params['status'], ['approved', 'rejected'])) {
                $this->error(__('审批状态不正确'));
            }
            
            try {
                $result = $row->save([
                    'status' => $params['status'],
                    'approver_id' => $this->auth->id,
                    'approval_time' => date('Y-m-d H:i:s'),
                    'remarks' => $params['remarks'] ?? ''
                ]);
                
                if ($result !== false) {
                    $this->success('审批成功');
                } else {
                    $this->error(__('审批失败'));
                }
            } catch (Exception | PDOException $e) {
                $this->error($e->getMessage());
            }
        }
        
        // 加载明细和关联数据
        $row = $row->with([
            'supplier', 
            'warehouse', 
            'creator',
            'details.product'
        ])->find($ids);
            
        $this->assign('row', $row);
        return $this->view->fetch();
    }
    
    /**
     * 取消订单
     */
    public function cancel($ids = null)
    {
        $row = $this->model->find($ids);
        if (!$row) {
            $this->error(__('数据不存在'));
        }
        
        // 只有草稿或待审批状态的订单可以取消
        if (!in_array($row['status'], ['draft', 'pending'])) {
            $this->error(__('只有草稿或待审批状态的采购单可以取消'));
        }
        
        if ($this->request->isPost()) {
            $params = $this->request->post();
            
            if (empty($params['reason'])) {
                $this->error(__('取消原因不能为空'));
            }
            
            try {
                $result = $row->save([
                    'status' => 'cancelled',
                    'cancel_time' => date('Y-m-d H:i:s'),
                    'cancel_reason' => $params['reason']
                ]);
                
                if ($result !== false) {
                    $this->success('取消成功');
                } else {
                    $this->error(__('取消失败'));
                }
            } catch (Exception | PDOException $e) {
                $this->error($e->getMessage());
            }
        }
        
        $this->error(__('请求类型错误'));
    }
    
    /**
     * 完成订单
     */
    public function complete($ids = null)
    {
        $row = $this->model->find($ids);
        if (!$row) {
            $this->error(__('数据不存在'));
        }
        
        // 只有已审批状态的订单可以标记完成
        if ($row['status'] !== 'approved') {
            $this->error(__('只有已审批状态的采购单可以标记完成'));
        }
        
        try {
            $result = $row->save([
                'status' => 'completed',
                'complete_time' => date('Y-m-d H:i:s')
            ]);
            
            if ($result !== false) {
                $this->success('操作成功');
            } else {
                $this->error(__('操作失败'));
            }
        } catch (Exception | PDOException $e) {
            $this->error($e->getMessage());
        }
    }
    
    /**
     * 获取统计数据
     */
    public function stats()
    {
        $timeUnit = $this->request->param('timeUnit', 'day');
        
        // 获取统计范围
        $startTime = '';
        $endTime = date('Y-m-d H:i:s');
        
        if ($timeUnit == 'day') {
            $startTime = date('Y-m-d 00:00:00');
        } elseif ($timeUnit == 'month') {
            $startTime = date('Y-m-01 00:00:00');
        } elseif ($timeUnit == 'quarter') {
            $quarter = ceil(date('n') / 3);
            $startTime = date('Y-' . (($quarter - 1) * 3 + 1) . '-01 00:00:00');
        } else {
            $this->error(__('时间单位不正确'));
        }
        
        // 获取当前周期的数据
        $currentPurchaseAmount = $this->model
            ->where('create_time', 'between', [$startTime, $endTime])
            ->sum('total_amount');
            
        $currentOrderCount = $this->model
            ->where('create_time', 'between', [$startTime, $endTime])
            ->count();
            
        $pendingOrders = $this->model
            ->where('status', 'pending')
            ->count();
            
        // 计算与上一周期比较的变化率
        $prevStartTime = '';
        $prevEndTime = $startTime;
        
        if ($timeUnit == 'day') {
            // 前一天
            $prevStartTime = date('Y-m-d 00:00:00', strtotime('-1 day'));
        } elseif ($timeUnit == 'month') {
            // 上个月
            $prevStartTime = date('Y-m-01 00:00:00', strtotime('-1 month'));
        } elseif ($timeUnit == 'quarter') {
            // 上个季度
            $prevStartTime = date('Y-' . (($quarter - 2 <= 0 ? 4 + $quarter - 2 : $quarter - 2) * 3 + 1) . '-01 00:00:00');
            if ($quarter == 1) {
                $prevStartTime = date('Y-10-01 00:00:00', strtotime('-1 year'));
            }
        }
        
        $prevPurchaseAmount = $this->model
            ->where('create_time', 'between', [$prevStartTime, $prevEndTime])
            ->sum('total_amount');
            
        $prevOrderCount = $this->model
            ->where('create_time', 'between', [$prevStartTime, $prevEndTime])
            ->count();
            
        $prevPendingOrders = $this->model
            ->where('status', 'pending')
            ->where('create_time', '<', $startTime)
            ->count();
            
        // 计算变化率
        $purchaseAmountChange = ($prevPurchaseAmount > 0) ? 
            round(($currentPurchaseAmount - $prevPurchaseAmount) / $prevPurchaseAmount * 100, 2) : 0;
            
        $orderCountChange = ($prevOrderCount > 0) ? 
            round(($currentOrderCount - $prevOrderCount) / $prevOrderCount * 100, 2) : 0;
            
        $pendingOrdersChange = ($prevPendingOrders > 0) ? 
            round(($pendingOrders - $prevPendingOrders) / $prevPendingOrders * 100, 2) : 0;
        
        // 模拟节约成本数据
        $costSavings = round($currentPurchaseAmount * 0.15);
        $prevCostSavings = round($prevPurchaseAmount * 0.15);
        $costSavingsChange = ($prevCostSavings > 0) ? 
            round(($costSavings - $prevCostSavings) / $prevCostSavings * 100, 2) : 0;
        
        $result = [
            'purchaseAmount' => [
                'value' => $currentPurchaseAmount ?: 0,
                'change' => $purchaseAmountChange,
                'changeType' => $purchaseAmountChange >= 0 ? 'increase' : 'decrease'
            ],
            'orderCount' => [
                'value' => $currentOrderCount ?: 0,
                'change' => $orderCountChange,
                'changeType' => $orderCountChange >= 0 ? 'increase' : 'decrease'
            ],
            'costSavings' => [
                'value' => $costSavings ?: 0,
                'change' => $costSavingsChange,
                'changeType' => $costSavingsChange >= 0 ? 'increase' : 'decrease'
            ],
            'pendingOrders' => [
                'value' => $pendingOrders ?: 0,
                'change' => $pendingOrdersChange,
                'changeType' => $pendingOrdersChange >= 0 ? 'increase' : 'decrease'
            ]
        ];
        
        $this->success('获取成功', null, $result);
    }
    
    /**
     * 获取趋势数据
     */
    public function trend()
    {
        $startDate = $this->request->param('startDate');
        $endDate = $this->request->param('endDate');
        
        if (empty($startDate) || empty($endDate)) {
            // 默认查询最近14天的数据
            $endDate = date('Y-m-d');
            $startDate = date('Y-m-d', strtotime('-13 days'));
        }
        
        $result = [];
        $current = strtotime($startDate);
        $end = strtotime($endDate);
        
        while ($current <= $end) {
            $date = date('Y-m-d', $current);
            $dayStart = $date . ' 00:00:00';
            $dayEnd = $date . ' 23:59:59';
            
            // 查询当天的数据
            $amountData = $this->model
                ->where('create_time', 'between', [$dayStart, $dayEnd])
                ->sum('total_amount');
                
            $countData = $this->model
                ->where('create_time', 'between', [$dayStart, $dayEnd])
                ->count();
                
            // 模拟节约成本数据
            $savingsData = round($amountData * 0.15);
            
            $result[] = [
                'date' => $date,
                'amount' => $amountData ?: 0,
                'count' => $countData ?: 0,
                'savings' => $savingsData ?: 0
            ];
            
            $current = strtotime('+1 day', $current);
        }
        
        $this->success('获取成功', null, $result);
    }
    
    /**
     * 获取最近订单
     */
    public function recent()
    {
        $limit = $this->request->param('limit', 5);
        $status = $this->request->param('status');
        
        $where = [];
        if (!empty($status)) {
            $where[] = ['status', '=', $status];
        }
        
        $list = $this->model
            ->with(['supplier', 'creator'])
            ->where($where)
            ->order('create_time', 'desc')
            ->limit($limit)
            ->select();
            
        $this->success('获取成功', null, $list);
    }
    
    /**
     * 下拉选择
     */
    protected function select()
    {
        $params = $this->request->get();
        
        $list = $this->model
            ->with(['supplier'])
            ->where('status', 'completed')
            ->order('create_time', 'desc')
            ->select();
            
        $result = ['total' => count($list), 'rows' => $list];
        
        return json($result);
    }
    
    /**
     * 生成订单编号
     */
    protected function generateOrderNo()
    {
        $date = date('Ymd');
        $start = $date . '0001';
        $end = $date . '9999';
        
        $lastOrder = $this->model
            ->where('order_no', 'between', [$start, $end])
            ->order('order_no', 'desc')
            ->value('order_no');
            
        if ($lastOrder) {
            $number = intval(substr($lastOrder, -4));
            $number += 1;
            return $date . str_pad($number, 4, '0', STR_PAD_LEFT);
        } else {
            return $date . '0001';
        }
    }
} 